home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / LZHUF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-30  |  32.7 KB  |  1,341 lines

  1. /* This STANDALONE variable doesn't work to build a Standalone LZHUF executable. */
  2. #undef  STANDALONE
  3. /*
  4.  ************************************************************
  5.  lzhuf.c
  6.  written by Haruyasu Yoshizaki 11/20/1988
  7.  some minor changes 4/6/1989
  8.  comments translated by Haruhiko Okumura 4/7/1989
  9.  ************************************************************
  10.  */
  11. #ifndef MSDOS
  12. #include "ctype.h"
  13. #endif
  14. #ifndef STANDALONE
  15. #include "global.h"
  16. #include <time.h>
  17. #include "forward.h"
  18. #else
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #define LZHUF 1
  23. #define mallocw malloc
  24. #endif
  25.  
  26. #if defined(LZHUF) || defined(FBBCMP)
  27. #ifndef MSDOS
  28. #include "session.h"
  29. #endif
  30.  
  31. #undef  DEBUG
  32. #undef  DEBUG2
  33.  
  34. #if !defined(_lint)
  35. static char rcsid[] OPTIONAL = "$Id: lzhuf.c,v 1.16 1997/07/31 00:44:20 root Exp root $";
  36. #endif
  37.  
  38. #if defined(CATALOG) && !defined(STANDALONE)
  39. #include "catalog.h"
  40.  
  41. #define CAT lzhuf_catalog
  42.  
  43. #define ErrorEncode    __STR(0)
  44. #define lostremote    __STR(1)
  45. #define ErrorDecode    __STR(2)
  46. #define Erroropening    __STR(3)
  47. #define ENCODEratio    __STR(4)
  48. #define DECODEratio    __STR(5)
  49.  
  50. #else /* CATALOG */
  51. static const char ErrorEncode[] = "FWDCMP: Error from Encode() rc = %d";
  52. static const char lostremote[] = "FBBFWD: Lost the remote connection in recv_yapp()";
  53. static const char ErrorDecode[] = "FWDCMP: Error from Decode() rc = %d";
  54. static const char Erroropening[] = "FBBFWD: Error opening %s in %s\n";
  55. static const char ENCODEratio[] = "FWDCMP: ENCODE:  In: %-8ld  Out: %-8ld (%ld%%)\n";
  56. static const char DECODEratio[] = "FWDCMP: DECODE:  In: %-8ld  Out: %-8ld (%ld%%)\n";
  57.  
  58. #endif /* CATALOG */
  59.  
  60.  
  61. static const char Encodestr[] = "Encode()";
  62. static const char Decodestr[] = "Decode()";
  63.  
  64. #ifdef STANDALONE
  65. #undef free
  66. #undef malloc
  67. #define tcmdprintf printf
  68. int FBBtrace = 1;
  69. #endif
  70.  
  71.  
  72.  
  73. static void 
  74. AllocDataBuffers (struct fwd *f)
  75. {
  76.     f->lzhuf = mallocw (sizeof (struct lzhufstruct));
  77. #if 0
  78.     f->tmpBuffer = mallocw (260);
  79. #endif
  80.  
  81.     f->lzhuf->data_type = 0;        /* 0 means not allocated yet. */
  82.     f->lzhuf->data = mallocw (sizeof (struct lzhufdata));
  83.  
  84.     if (f->lzhuf->data != NULLLZHUFDATA)
  85.         f->lzhuf->data_type = 2;    /* 2 means big buffer + lower memory. */
  86.  
  87.     if (f->lzhuf->data_type == 0) {
  88.         f->lzhuf->data_type = 1;    /* 1 means small buffers + lower memory. */
  89.         f->lzhuf->dad = mallocw ((N + 1) * sizeof (int));
  90.         f->lzhuf->lson = mallocw ((N + 1) * sizeof (int));
  91.         f->lzhuf->rson = mallocw ((N + 257) * sizeof (int));
  92.         f->lzhuf->text_buf = mallocw ((N + F - 1) * sizeof (unsigned char));
  93.         f->lzhuf->freq = mallocw ((T + 1) * sizeof (unsigned));
  94.         f->lzhuf->prnt = mallocw ((T + N_CHAR) * sizeof (int));
  95.         f->lzhuf->son = mallocw ((T) * sizeof (int));
  96.     } else {
  97.         /* point pointers to correct spot in large buffer. */
  98.         f->lzhuf->dad = f->lzhuf->data->dad;
  99.         f->lzhuf->rson = f->lzhuf->data->rson;
  100.         f->lzhuf->lson = f->lzhuf->data->lson;
  101.         f->lzhuf->text_buf = f->lzhuf->data->text_buf;
  102.         f->lzhuf->freq = f->lzhuf->data->freq;
  103.         f->lzhuf->prnt = f->lzhuf->data->prnt;
  104.         f->lzhuf->son = f->lzhuf->data->son;
  105.     }
  106.     f->lzhuf->codesize = 0;
  107.     f->lzhuf->getbuf = 0;
  108.     f->lzhuf->getlen = 0;
  109.     f->lzhuf->putbuf = 0;
  110.     f->lzhuf->putlen = 0;
  111.     f->lzhuf->code = 0;
  112.     f->lzhuf->len = 0;
  113. }
  114.  
  115.  
  116.  
  117. static void 
  118. FreeDataBuffers (struct fwd *f)
  119. {
  120. #if 0
  121.     free (f->tmpBuffer);
  122. #endif
  123.  
  124.     if (f->lzhuf->data_type == 1) {
  125.         /* Free lower memory blocks. */
  126.         free (f->lzhuf->dad);
  127.         free (f->lzhuf->lson);
  128.         free (f->lzhuf->rson);
  129.         free (f->lzhuf->text_buf);
  130.         free (f->lzhuf->freq);
  131.         free (f->lzhuf->prnt);
  132.         free (f->lzhuf->son);
  133.     } else if (f->lzhuf->data_type == 2) {
  134.         /* Free lower memory block. */
  135.         free (f->lzhuf->data);
  136.     }
  137.     free (f->lzhuf);
  138.     f->lzhuf = NULLLZHUFSTRUCT;
  139. }
  140.  
  141.  
  142.  
  143. static int Encode (int, char *, char *, struct lzhufstruct *, int trace);
  144. static int Decode (int, char *, char *, struct lzhufstruct *, int addex, int trace);
  145. static int GetBit (struct lzhufstruct *);
  146. static unsigned short GetByte (struct lzhufstruct *);
  147. static void Putcode (struct lzhufstruct *, int, unsigned);
  148. static void EncodeEnd (struct lzhufstruct *);
  149. static int DecodeChar (struct lzhufstruct *);
  150.  
  151.  
  152. static void InitTree (struct lzhufstruct *);
  153. static void InsertNode (struct lzhufstruct *, int);
  154. static void StartHuff (struct lzhufstruct *);
  155. static void reconst (struct lzhufstruct *);
  156. static void lzhuf_update (struct lzhufstruct *, int);
  157. static void EncodeChar (struct lzhufstruct *, unsigned);
  158. static void EncodePosition (struct lzhufstruct *, unsigned);
  159. static int DecodePosition (struct lzhufstruct *);
  160. static void DeleteNode (struct lzhufstruct *, int);
  161. static int recvbuf (int, char *, unsigned);
  162.  
  163. /********** LZSS compression **********/
  164.  
  165.  
  166.  
  167. static void 
  168. InitTree (struct lzhufstruct *lzhuf)
  169. {            /* initialize trees */
  170. int i;
  171.  
  172.     for (i = N + 1; i <= N + 256; i++)
  173.         lzhuf->rson[i] = NIL;    /* root */
  174.     for (i = 0; i < N; i++)
  175.         lzhuf->dad[i] = NIL;    /* node */
  176. }
  177.  
  178.  
  179.  
  180. static void 
  181. InsertNode (struct lzhufstruct *lzhuf, int r)
  182. {            /* insert to tree */
  183. int i, p, cmp;
  184. unsigned char *key;
  185. unsigned c;
  186.  
  187.     cmp = 1;
  188.     key = &lzhuf->text_buf[r];
  189.     p = N + 1 + key[0];
  190.     lzhuf->rson[r] = lzhuf->lson[r] = NIL;
  191.     lzhuf->match_length = 0;
  192.     for (;;) {
  193.         if (cmp >= 0) {
  194.             if (lzhuf->rson[p] != NIL)
  195.                 p = lzhuf->rson[p];
  196.             else {
  197.                 lzhuf->rson[p] = r;
  198.                 lzhuf->dad[r] = p;
  199.                 return;
  200.             }
  201.         } else {
  202.             if (lzhuf->lson[p] != NIL)
  203.                 p = lzhuf->lson[p];
  204.             else {
  205.                 lzhuf->lson[p] = r;
  206.                 lzhuf->dad[r] = p;
  207.                 return;
  208.             }
  209.         }
  210.         for (i = 1; i < F; i++)
  211.             if ((cmp = key[i] - lzhuf->text_buf[p + i]) != 0)
  212.                 break;
  213.         if (i > THRESHOLD) {
  214.             if (i > lzhuf->match_length) {
  215.                 lzhuf->match_position = ((r - p) & (N - 1)) - 1;
  216.                 if ((lzhuf->match_length = i) >= F)
  217.                     break;
  218.             }
  219.             if (i == lzhuf->match_length) {
  220.                 if ((c = ((r - p) & (N - 1)) - 1) < (unsigned) lzhuf->match_position)
  221.                     lzhuf->match_position = (int) c;
  222.             }
  223.         }
  224.     }
  225.     lzhuf->dad[r] = lzhuf->dad[p];
  226.     lzhuf->lson[r] = lzhuf->lson[p];
  227.     lzhuf->rson[r] = lzhuf->rson[p];
  228.     lzhuf->dad[lzhuf->lson[p]] = r;
  229.     lzhuf->dad[lzhuf->rson[p]] = r;
  230.     if (lzhuf->rson[lzhuf->dad[p]] == p)
  231.         lzhuf->rson[lzhuf->dad[p]] = r;
  232.     else
  233.         lzhuf->lson[lzhuf->dad[p]] = r;
  234.     lzhuf->dad[p] = NIL;    /* remove p */
  235. }
  236.  
  237.  
  238.  
  239. static void 
  240. DeleteNode (struct lzhufstruct *lzhuf, int p)
  241. {            /* remove from tree */
  242. int q;
  243.  
  244.     if (lzhuf->dad[p] == NIL)
  245.         return;        /* not registered */
  246.     if (lzhuf->rson[p] == NIL)
  247.         q = lzhuf->lson[p];
  248.     else if (lzhuf->lson[p] == NIL)
  249.         q = lzhuf->rson[p];
  250.     else {
  251.         q = lzhuf->lson[p];
  252.         if (lzhuf->rson[q] != NIL) {
  253.             do {
  254.                 q = lzhuf->rson[q];
  255.             } while (lzhuf->rson[q] != NIL);
  256.             lzhuf->rson[lzhuf->dad[q]] = lzhuf->lson[q];
  257.             lzhuf->dad[lzhuf->lson[q]] = lzhuf->dad[q];
  258.             lzhuf->lson[q] = lzhuf->lson[p];
  259.             lzhuf->dad[lzhuf->lson[p]] = q;
  260.         }
  261.         lzhuf->rson[q] = lzhuf->rson[p];
  262.         lzhuf->dad[lzhuf->rson[p]] = q;
  263.     }
  264.     lzhuf->dad[q] = lzhuf->dad[p];
  265.     if (lzhuf->rson[lzhuf->dad[p]] == p)
  266.         lzhuf->rson[lzhuf->dad[p]] = q;
  267.     else
  268.         lzhuf->lson[lzhuf->dad[p]] = q;
  269.     lzhuf->dad[p] = NIL;
  270. }
  271.  
  272.  
  273.  
  274. /* Huffman coding */
  275.  
  276. /* table for encoding and decoding the upper 6 bits of position */
  277.  
  278. /* for encoding */
  279. #define MAX_P_LEN 64
  280. static uint8 p_len[MAX_P_LEN] =
  281. {
  282.     0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
  283.     0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
  284.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  285.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  286.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  287.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  288.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  289.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
  290. };
  291.  
  292. static uint8 p_code[MAX_P_LEN] =
  293. {
  294.     0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
  295.     0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
  296.     0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
  297.     0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
  298.     0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
  299.     0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
  300.     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  301.     0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  302. };
  303.  
  304. /* for decoding */
  305. #define MAX_D_LEN 256
  306. static uint8 d_code[MAX_D_LEN] =
  307. {
  308.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  309.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  310.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  311.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  312.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  313.     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  314.     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  315.     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  316.     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  317.     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  318.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  319.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  320.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  321.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  322.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  323.     0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
  324.     0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
  325.     0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
  326.     0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
  327.     0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
  328.     0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
  329.     0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
  330.     0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
  331.     0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
  332.     0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
  333.     0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
  334.     0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
  335.     0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
  336.     0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
  337.     0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
  338.     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  339.     0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  340. };
  341.  
  342. static uint8 d_len[MAX_D_LEN] =
  343. {
  344.     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  345.     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  346.     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  347.     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  348.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  349.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  350.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  351.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  352.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  353.     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  354.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  355.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  356.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  357.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  358.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  359.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  360.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  361.     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  362.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  363.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  364.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  365.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  366.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  367.     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  368.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  369.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  370.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  371.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  372.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  373.     0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  374.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  375.     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  376. };
  377.  
  378.  
  379.  
  380. static int 
  381. GetBit (struct lzhufstruct *lzhuf)
  382. {            /* get one bit */
  383. register unsigned i;
  384. register unsigned dx = lzhuf->getbuf;
  385. register unsigned char glen = lzhuf->getlen;
  386.  
  387.     while (glen <= 8) {
  388.         i = (unsigned) getc (lzhuf->iFile);
  389.         if ((int) i < 0)
  390.             i = 0;
  391.         dx |= i << (8 - glen);
  392.         glen += 8;
  393.     }
  394.     lzhuf->getbuf = dx << 1;
  395.     lzhuf->getlen = glen - 1;
  396.     return (dx & 0x8000) ? 1 : 0;
  397. }
  398.  
  399.  
  400.  
  401. static unsigned short 
  402. GetByte (struct lzhufstruct *lzhuf)
  403. {            /* get one byte */
  404. register unsigned i;
  405. register unsigned dx = lzhuf->getbuf;
  406. register unsigned char glen = lzhuf->getlen;
  407.  
  408.     while (glen <= 8) {
  409.         i = (unsigned) getc (lzhuf->iFile);
  410.         if ((int) i < 0)
  411.             i = 0;
  412.         dx |= i << (8 - glen);
  413.         glen += 8;
  414.     }
  415.     lzhuf->getbuf = dx << 8;
  416.     lzhuf->getlen = glen - 8;
  417.     return (dx >> 8) & 0xff;
  418. }
  419.  
  420.  
  421.  
  422. static void 
  423. Putcode (struct lzhufstruct *lzhuf, int l, unsigned c)
  424. {            /* output c bits of code */
  425.     lzhuf->putbuf |= c >> lzhuf->putlen;
  426.     if ((lzhuf->putlen += uchar (l)) >= 8) {
  427.         if (putc (lzhuf->putbuf >> 8, lzhuf->oFile) == EOF)
  428.             return;
  429.  
  430.         if ((lzhuf->putlen -= 8) >= 8) {
  431.             if (putc ((int) lzhuf->putbuf, lzhuf->oFile) == EOF)
  432.                 return;
  433.  
  434.             lzhuf->codesize += 2;
  435.             lzhuf->putlen -= 8;
  436.             lzhuf->putbuf = c << (l - lzhuf->putlen);
  437.         } else {
  438.             lzhuf->putbuf <<= 8;
  439.             lzhuf->codesize++;
  440.         }
  441.     }
  442. }
  443.  
  444.  
  445.  
  446. /* initialization of tree */
  447.  
  448. static void 
  449. StartHuff (struct lzhufstruct *lzhuf)
  450. {
  451. int i, j;
  452.  
  453.     for (i = 0; i < N_CHAR; i++) {
  454.         lzhuf->freq[i] = 1;
  455.         lzhuf->son[i] = i + T;
  456.         lzhuf->prnt[i + T] = i;
  457.     }
  458.     i = 0;
  459.     j = N_CHAR;
  460.     while (j <= R) {
  461.         lzhuf->freq[j] = lzhuf->freq[i] + lzhuf->freq[i + 1];
  462.         lzhuf->son[j] = i;
  463.         lzhuf->prnt[i] = lzhuf->prnt[i + 1] = j;
  464.         i += 2;
  465.         j++;
  466.     }
  467.     lzhuf->freq[T] = 0xffff;
  468.     lzhuf->prnt[R] = 0;
  469.     lzhuf->putlen = lzhuf->getlen = 0;
  470.     lzhuf->putbuf = lzhuf->getbuf = 0;
  471. }
  472.  
  473.  
  474.  
  475. /* reconstruction of tree */
  476. static void 
  477. reconst (struct lzhufstruct *lzhuf)
  478. {
  479. int i, j, k;
  480. unsigned first;
  481.  
  482.     /* collect leaf nodes in the first half of the table */
  483.     /* and replace the freq by (freq + 1) / 2. */
  484.     j = 0;
  485.     for (i = 0; i < T; i++) {
  486.         if (lzhuf->son[i] >= T) {
  487.             lzhuf->freq[j] = (lzhuf->freq[i] + 1) / 2;
  488.             lzhuf->son[j] = lzhuf->son[i];
  489.             j++;
  490.         }
  491.     }
  492.     /* begin constructing tree by connecting sons */
  493.     for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
  494.         k = i + 1;
  495.         first = lzhuf->freq[j] = lzhuf->freq[i] + lzhuf->freq[k];
  496.         for (k = j - 1; first < lzhuf->freq[k]; k--)
  497.             ;
  498.         k++;
  499.         {
  500.             register unsigned *p, *e;
  501.  
  502.             for (p = &lzhuf->freq[j], e = &lzhuf->freq[k]; p > e; p--)
  503.                 p[0] = p[-1];
  504.             lzhuf->freq[k] = first;
  505.         }
  506.         {
  507.             register int *p, *e;
  508.  
  509.             for (p = &lzhuf->son[j], e = &lzhuf->son[k]; p > e; p--)
  510.                 p[0] = p[-1];
  511.             lzhuf->son[k] = i;
  512.         }
  513.     }
  514.     /* connect prnt */
  515.     for (i = 0; i < T; i++) {
  516.         if ((k = lzhuf->son[i]) >= T)
  517.             lzhuf->prnt[k] = i;
  518.         else
  519.             lzhuf->prnt[k] = lzhuf->prnt[k + 1] = i;
  520.     }
  521. }
  522.  
  523.  
  524.  
  525. /* increment frequency of given code by one, and update tree */
  526. void 
  527. lzhuf_update (struct lzhufstruct *lzhuf, int c)
  528. {
  529. int i, j, k, l;
  530.  
  531.     if (lzhuf->freq[R] == MAX_FREQ)
  532.         reconst (lzhuf);
  533.  
  534.     c = lzhuf->prnt[c + T];
  535.     do {
  536.         k = (int) ++lzhuf->freq[c];
  537.  
  538.         /* if the order is disturbed, exchange nodes */
  539.         if ((unsigned) k > lzhuf->freq[l = c + 1]) {
  540.             while ((unsigned) k > lzhuf->freq[++l])
  541.                 ;
  542.             l--;
  543.             lzhuf->freq[c] = lzhuf->freq[l];
  544.             lzhuf->freq[l] = (unsigned int) k;
  545.  
  546.             i = lzhuf->son[c];
  547.             lzhuf->prnt[i] = l;
  548.             if (i < T)
  549.                 lzhuf->prnt[i + 1] = l;
  550.  
  551.             j = lzhuf->son[l];
  552.             lzhuf->son[l] = i;
  553.  
  554.             lzhuf->prnt[j] = c;
  555.             if (j < T)
  556.                 lzhuf->prnt[j + 1] = c;
  557.             lzhuf->son[c] = j;
  558.  
  559.             c = l;
  560.         }
  561.     } while ((c = lzhuf->prnt[c]) != 0);    /* repeat up to root */
  562. }
  563.  
  564.  
  565.  
  566. static void 
  567. EncodeChar (struct lzhufstruct *lzhuf, unsigned c)
  568. {
  569. unsigned i;
  570. int j, k;
  571.  
  572.     i = 0;
  573.     j = 0;
  574.     k = lzhuf->prnt[c + T];
  575.  
  576.     /* travel from leaf to root */
  577.     do {
  578.         i >>= 1;
  579.  
  580.         /* if node's address is odd-numbered, choose bigger brother node */
  581.         if (k & 1)
  582.             i += 0x8000;
  583.  
  584.         j++;
  585.     } while ((k = lzhuf->prnt[k]) != R);
  586.     Putcode (lzhuf, j, i);
  587.     lzhuf->code = i;
  588.     lzhuf->len = (unsigned int) j;
  589.     lzhuf_update (lzhuf, (int) c);
  590. }
  591.  
  592.  
  593.  
  594. static void 
  595. EncodePosition (struct lzhufstruct *lzhuf, unsigned c)
  596. {
  597. unsigned i;
  598.  
  599.     /* output upper 6 bits by table lookup */
  600.     i = c >> 6;
  601. #ifdef DEBUG
  602.     if (i >= MAX_P_LEN)
  603.         tcmdprintf ("Ah....FYI...you've just exceded the MAX_P_LEN variable ( %d ) with %d\n", MAX_P_LEN, i);
  604. #endif
  605.     Putcode (lzhuf, p_len[i], (unsigned) p_code[i] << 8);
  606.  
  607.     /* output lower 6 bits verbatim */
  608.     Putcode (lzhuf, 6, (c & 0x3f) << 10);
  609. }
  610.  
  611.  
  612.  
  613. static void 
  614. EncodeEnd (struct lzhufstruct *lzhuf)
  615. {
  616.     if (lzhuf->putlen) {
  617.         if (putc (lzhuf->putbuf >> 8, lzhuf->oFile) == EOF)
  618.             return;
  619.         lzhuf->codesize++;
  620.     }
  621. }
  622.  
  623.  
  624.  
  625. static int 
  626. DecodeChar (struct lzhufstruct *lzhuf)
  627. {
  628. unsigned c;
  629.  
  630.     c = (unsigned) lzhuf->son[R];
  631.  
  632.     /* travel from root to leaf, */
  633.     /* choosing the smaller child node (son[]) if the read bit is 0, */
  634.     /* the bigger (son[]+1} if 1 */
  635.     while (c < T) {
  636.         c += (unsigned) GetBit (lzhuf);
  637.         c = (unsigned) lzhuf->son[c];
  638.     }
  639.     c -= T;
  640.     lzhuf_update (lzhuf, (int) c);
  641.     return (int) c;
  642. }
  643.  
  644.  
  645.  
  646. static int 
  647. DecodePosition (struct lzhufstruct *lzhuf)
  648. {
  649. unsigned j, c;
  650. unsigned short i;
  651.  
  652.     /* recover upper 6 bits from table */
  653.     i = GetByte (lzhuf);
  654. #ifdef DEBUG
  655.     if (i >= MAX_D_LEN)
  656.         tcmdprintf ("Ah....FYI...you've just exceded the MAX_D_LEN variable ( %u ) with %u\n", MAX_D_LEN, i);
  657. #endif
  658.     c = (unsigned) d_code[i] << 6;
  659.     j = d_len[i];
  660.  
  661.     /* read lower 6 bits verbatim */
  662.     j -= 2;
  663.     while (j--)
  664.         i = (int16) ((i << 1) + GetBit (lzhuf));
  665.  
  666.     return (int) (c | (i & 0x3f));
  667. }
  668.  
  669.  
  670.  
  671. /* compression */
  672. static int 
  673. Encode (int usock OPTIONAL, char *txtFileName, char *binFileName, struct lzhufstruct *lzhuf, int trace)
  674. {
  675. int i, c, len, r, s, last_match_length;
  676. unsigned long int filesize = 0;
  677.  
  678. #ifdef DEBUG
  679.     tcmdprintf ("Encoding %s into %s\n", txtFileName, binFileName);
  680. #endif
  681.  
  682.     /* Open input and output files. */
  683.     if ((lzhuf->iFile = fopen (txtFileName, "rb")) == NULLFILE) {
  684.         if (trace)
  685.             tcmdprintf (Erroropening, txtFileName, Encodestr);
  686.         return 0;
  687.     }
  688.     if ((lzhuf->oFile = fopen (binFileName, "wb")) == NULLFILE) {
  689.         if (trace)
  690.             tcmdprintf (Erroropening, binFileName, Encodestr);
  691.         return 0;
  692.     }
  693.     fseek (lzhuf->iFile, 0L, 2);
  694.     filesize = (unsigned long) ftell (lzhuf->iFile);
  695.     if (filesize == 0)
  696.         return 0;
  697.     /* output size of text */
  698.     if (fwrite (&filesize, sizeof (filesize), 1, lzhuf->oFile) < 1)
  699.         return 0;
  700.     rewind (lzhuf->iFile);
  701.  
  702.     lzhuf->iFileSize = filesize;
  703.     filesize = 0;        /* rewind and re-read */
  704.  
  705.     StartHuff (lzhuf);
  706.     InitTree (lzhuf);
  707.  
  708.     s = 0;
  709.     r = N - F;
  710.     for (i = s; i < r; i++)
  711.         lzhuf->text_buf[i] = ' ';
  712.     for (len = 0; len < F && (c = getc (lzhuf->iFile)) != EOF; len++)
  713.         lzhuf->text_buf[r + len] = uchar (c);
  714.     filesize = (unsigned long) len;
  715.     for (i = 1; i <= F; i++)
  716.         InsertNode (lzhuf, r - i);
  717.     InsertNode (lzhuf, r);
  718.     do {
  719.         kwait (NULL);
  720.         if (lzhuf->match_length > len)
  721.             lzhuf->match_length = len;
  722.         if (lzhuf->match_length <= THRESHOLD) {
  723.             lzhuf->match_length = 1;
  724.             EncodeChar (lzhuf, lzhuf->text_buf[r]);
  725.         } else {
  726.             EncodeChar (lzhuf, (unsigned) (255 - THRESHOLD + lzhuf->match_length));
  727.             EncodePosition (lzhuf, (unsigned) lzhuf->match_position);
  728.         }
  729.         last_match_length = lzhuf->match_length;
  730.         for (i = 0; i < last_match_length && (c = getc (lzhuf->iFile)) != EOF; i++) {
  731.             DeleteNode (lzhuf, s);
  732.             lzhuf->text_buf[s] = uchar (c);
  733.             if (s < F - 1)
  734.                 lzhuf->text_buf[s + N] = uchar (c);
  735.             s = (s + 1) & (N - 1);
  736.             r = (r + 1) & (N - 1);
  737.             InsertNode (lzhuf, r);
  738.         }
  739.         while (i++ < last_match_length) {
  740.             DeleteNode (lzhuf, s);
  741.             s = (s + 1) & (N - 1);
  742.             r = (r + 1) & (N - 1);
  743.             if (--len)
  744.                 InsertNode (lzhuf, r);
  745.         }
  746.     } while (len > 0);
  747.     EncodeEnd (lzhuf);
  748.     (void) fclose (lzhuf->iFile);
  749.     (void) fclose (lzhuf->oFile);
  750.  
  751.     if (lzhuf->iFileSize == 0)
  752.         lzhuf->iFileSize = 1;
  753.     if (trace)
  754.         tcmdprintf (ENCODEratio, lzhuf->iFileSize, lzhuf->codesize,
  755.         (100 - ((lzhuf->codesize * 100) / (long) lzhuf->iFileSize)));
  756.     return 1;
  757. }
  758.  
  759.  
  760.  
  761. static int 
  762. Decode (int usock OPTIONAL, char *iFile, char *oFile, struct lzhufstruct *lzhuf, int addex, int trace)
  763. {
  764. int i = 0;
  765. int j = 0;
  766. int k = 0;
  767. int r = 0;
  768. int c = 0;
  769. unsigned long int count = 0;
  770. long int filesize = 0;
  771.  
  772. #ifdef DEBUG
  773.     tcmdprintf ("Decoding %s into %s\n", iFile, oFile);
  774. #endif
  775.  
  776.     /* Open input and output files. */
  777.     if ((lzhuf->iFile = fopen (iFile, "rb")) == NULLFILE) {
  778.         if (trace)
  779.             tcmdprintf (Erroropening, iFile, Decodestr);
  780.         return 0;
  781.     }
  782.     if ((lzhuf->oFile = fopen (oFile, "wb")) == NULLFILE) {
  783.         if (trace)
  784.             tcmdprintf (Erroropening, oFile, Decodestr);
  785.         return 0;
  786.     }
  787.     fseek (lzhuf->iFile, 0L, 2);
  788.     filesize = ftell (lzhuf->iFile);
  789.     if (filesize == 0)
  790.         return 0;
  791.     lzhuf->iFileSize = (unsigned long) filesize;
  792.     rewind (lzhuf->iFile);
  793.  
  794.     if (fread (&filesize, sizeof (filesize), 1, lzhuf->iFile) < 1)
  795.         return 0;
  796.     if (filesize == 0)
  797.         return 0;
  798.  
  799.     StartHuff (lzhuf);
  800.     for (i = 0; i < N - F; i++)
  801.         lzhuf->text_buf[i] = ' ';
  802.  
  803.     r = N - F;
  804.     for (count = 0; count < (unsigned long) filesize;) {
  805.         kwait (NULL);
  806.         c = DecodeChar (lzhuf);
  807.         if (c < 256) {
  808.             if (putc (c, lzhuf->oFile) == EOF)
  809.                 return 0;
  810.  
  811.             lzhuf->text_buf[r++] = uchar (c);
  812.             r &= (N - 1);
  813.             count++;
  814.         } else {
  815.             i = (r - DecodePosition (lzhuf) - 1) & (N - 1);
  816.             j = c - 255 + THRESHOLD;
  817.             for (k = 0; k < j; k++) {
  818.                 c = lzhuf->text_buf[(i + k) & (N - 1)];
  819.                 if (putc (c, lzhuf->oFile) == EOF)
  820.                     return 0;
  821.  
  822.                 lzhuf->text_buf[r++] = uchar (c);
  823.                 r &= (N - 1);
  824.                 count++;
  825.             }
  826.         }
  827.     }
  828.  
  829. #ifndef STANDALONE
  830.     if (addex)
  831.         /* This terminates a note. */
  832.         fputs ("\n/EX\n", lzhuf->oFile);
  833. #endif
  834.  
  835.     (void) fclose (lzhuf->iFile);
  836.     (void) fclose (lzhuf->oFile);
  837.  
  838.     if (count == 0)
  839.         count = 1;
  840.     if (trace)
  841.         tcmdprintf (DECODEratio, lzhuf->iFileSize, count,
  842.                 (100 - ((lzhuf->iFileSize * 100) / count)));
  843.     return 1;
  844. }
  845.  
  846.  
  847.  
  848. #ifndef STANDALONE
  849. int 
  850. send_yapp (struct fwd *f, char *txtFileName, char *subj)
  851. {
  852. #define SLEN 79        /* Maximum subject     */
  853. int oldmode;        /* Socket Mode holder. */
  854. char *buffer;        /* buffer data.        */
  855. int buffer_len;        /* buffer Length.      */
  856. int x;            /* misc counter.       */
  857. int cnt;        /* misc counter.       */
  858. int rc;
  859. int Error;
  860. int usock;
  861. short b_checksum;    /* buffer checksum.    */
  862. short f_checksum;    /* file checksum.      */
  863. FILE *binFile;
  864. char binFileName[80];
  865. #ifdef DEBUG2
  866. FILE *debug;
  867. #endif
  868.  
  869.     /* Debug info. */
  870. #ifdef DEBUG2
  871.     if (((debug = fopen (tmpnam (NULL), "wb")) == NULLFILE)) {
  872.         printf ("Error opening input file.\n");
  873.         return 0;
  874.     }
  875. #endif
  876.  
  877.     /* User socket */
  878.     usock = f->m->user;
  879.  
  880.     /* Encode code. */
  881.     (void) tmpnam (binFileName);
  882.  
  883.     Error = FALSE;
  884.  
  885.     kwait (NULL);
  886.     AllocDataBuffers (f);
  887.     rc = Encode (usock, txtFileName, binFileName, f->lzhuf, FBBtrace);
  888.     FreeDataBuffers (f);
  889.     kwait (NULL);
  890.     if (!rc) {
  891.         if (FBBtrace)
  892.             tcmdprintf (ErrorEncode, rc);
  893.         log (f->m->user, ErrorEncode, rc);
  894.         Error = TRUE;
  895.         unlink (binFileName);    /* just in case */
  896.     }
  897.     unlink (txtFileName);
  898.  
  899.     if (Error)
  900.         return 0;
  901.  
  902.     /* open the compressed data file. */
  903.     /* Now... we're going to read from the file and close it when we exit. */
  904.  
  905.     /* Open the input file. */
  906.     binFile = fopen (binFileName, "rb");
  907.     if (binFile == NULLFILE)
  908.         return 0;
  909.  
  910.     /* Debug info. */
  911. #ifdef DEBUG
  912.     tcmdprintf ("we opened %s for input.\n", f->oFile);
  913. #endif
  914.  
  915.     /* Grab some space. Largest YAPP packet is 250+ bytes. */
  916.     f->tmpBuffer = mallocw (260);
  917.     buffer = f->tmpBuffer;
  918.  
  919.     /* Set the socket to Binary mode since we'll be sending Binary data. */
  920.     oldmode = sockmode (usock, SOCK_BINARY);
  921.  
  922.     /* Send the subject buffer
  923.          The buffer is setup as follows:
  924.          Pos Data
  925.            1 SOH
  926.            2 Length of entire buffer ( 8 bytes + strlen(subject) )
  927.            3 Null terminated Subject string.
  928.            x Null terminated '0' string.
  929.      */
  930.  
  931.     /* Make sure that the subject strlen() is equal to or less than SLEN */
  932.     x = (int) strlen (subj);
  933.     if (x >= SLEN) {
  934.         x = SLEN;
  935.         subj[SLEN] = '\0';
  936.     }
  937.     /* length of subject + NULL + length of "     0" + NULL */
  938.     buffer_len = x + 1 + 6 + 1;
  939.  
  940.     /* Build the buffer. */
  941.     buffer[0] = SOH;    /* buffer_Type                */
  942.     buffer[1] = (char) buffer_len;    /* buffer_Len                 */
  943.     strcpy (&buffer[2], subj);    /* Subject info.              */
  944.     strcpy (&buffer[x + 3], "     0");    /* Always 0 for FBB Messages. */
  945.  
  946.     /* Now we can send it.                       */
  947.     /* buffer_len + 2 ( for the first two bytes. */
  948.     (void) usputbuf (usock, (unsigned char *) buffer, buffer_len + 2);
  949. #ifdef DEBUG2
  950.     fwrite (buffer, buffer_len + 2, 1, debug);
  951. #endif
  952.  
  953.     /* Send the data buffers. */
  954.     f_checksum = 0;
  955.     /* fill buffer with data. Bytes 0 and 1 are reserved. */
  956.     while ((x = (int) fread (&buffer[2], 1, 250, binFile)) > 0) {
  957.         /* prepare the buffer. */
  958.         buffer[0] = STX;/* buffer_Type       */
  959.         buffer[1] = (char) x;    /* buffer_Len        */
  960.  
  961.         b_checksum = 0;
  962.         for (cnt = 0; cnt < x; cnt++)
  963.             b_checksum += buffer[2 + cnt];    /* buffer checksum.  */
  964.  
  965. #if 0                /* must be for FBB 4.15C ?? */
  966.         buffer[x + 2] = ((-b_checksum) & 0xff);    /* Store b_checksum. */
  967. #endif
  968.  
  969.         /* and send it. */
  970.         (void) usputbuf (usock, (unsigned char *) buffer, (x + 2));
  971. #ifdef DEBUG2
  972.         fwrite (buffer, x + 2, 1, debug);
  973. #endif
  974.  
  975.         f_checksum += b_checksum;
  976.     }            /* endwhile */
  977.  
  978.     /* Send the EOT */
  979.     /* Prepare the buffer. */
  980.     buffer[0] = EOT;    /* buffer_Type */
  981.     buffer[1] = (char) ((-f_checksum) & 0xff);    /* Checksum.   */
  982.  
  983.     /* and send it. */
  984.     (void) usputbuf (usock, (unsigned char *) buffer, 2);
  985. #ifdef DEBUG2
  986.     fwrite (buffer, 2, 1, debug);
  987. #endif
  988.  
  989.     /* Terminate. */
  990.     (void) fclose (binFile);
  991.  
  992.     /* Delete binFileName */
  993.     unlink (binFileName);
  994.  
  995. #ifdef DEBUG2
  996.     (void) fclose (debug);
  997. #endif
  998.     free (f->tmpBuffer);
  999.     /* Set the socket back to it's orginal mode. */
  1000.     (void) sockmode (usock, oldmode);
  1001.     return 1;
  1002. }
  1003.  
  1004.  
  1005. int 
  1006. recv_yapp (struct fwd *f)
  1007. {
  1008. int recvcnt;
  1009. int packet_type;
  1010. unsigned int packet_size;
  1011. char packet_data[258];
  1012. int GetSubject;
  1013. int NoteDone;
  1014. int NoteError;
  1015. unsigned int rx_checksumctr;
  1016. unsigned int rx_checksum;
  1017. int rc;
  1018. int oldmode;        /* Socket Mode holder. */
  1019. FILE *iFile = NULLFILE;
  1020. int usock;
  1021.  
  1022.     /* User socket */
  1023.     usock = f->m->user;
  1024.  
  1025.     /* Set the socket to Binary mode since we'll be sending Binary data. */
  1026.     oldmode = sockmode (usock, SOCK_BINARY);
  1027.  
  1028.     GetSubject = TRUE;
  1029.     NoteDone = FALSE;
  1030.     NoteError = FALSE;
  1031.     rx_checksum = 0;
  1032.  
  1033.     while (!NoteDone) {
  1034.         /* Get the data packets. */
  1035.         packet_type = recvchar (usock);
  1036.  
  1037.         if (GetSubject) {
  1038.             if (packet_type != SOH) {
  1039.                 FBBerror (0, usock, f->m);
  1040.                 NoteDone = NoteError = TRUE;
  1041.                 continue;
  1042.             }
  1043.         } else if ((packet_type != STX) && (packet_type != EOT)) {
  1044.             /* Get the packet size. */
  1045.             packet_size = (unsigned int) recvchar (usock);
  1046.             FBBerror (3, usock, f->m);
  1047.             NoteDone = NoteError = TRUE;
  1048.             continue;
  1049.         }
  1050.         /* Get the packet size. */
  1051.         packet_size = (unsigned int) recvchar (usock);
  1052.         if (!packet_size)
  1053.             packet_size = 256;    /* 0x00 always means 256 */
  1054.  
  1055.         if (packet_type == SOH) {
  1056.             /* This is the subject. Reset the flag so we don't */
  1057.             /* come here again.                                */
  1058.             GetSubject = FALSE;
  1059.  
  1060.             /* Open the output file. */
  1061.             if (iFile == NULLFILE)    /* shouldn't be needed, but just in case */
  1062.                 if ((iFile = fopen (f->iFile, "wb")) == NULLFILE)
  1063.                     return 0;
  1064.  
  1065.             /* This is a subject packet (with the offset hiding behind it). */
  1066.             recvcnt = recvbuf (usock, &packet_data[0], packet_size + 1);
  1067.             /* we have now read the subject (which we'll use) and the
  1068.                offset (which we are assuming to be zero), which we ignore */
  1069.             if (recvcnt == -1) {
  1070.                 if (FBBtrace) {
  1071.                     tcmdprintf (lostremote);
  1072.                     tcmdprintf ("\n");
  1073.                 }
  1074.                 log (f->m->user, lostremote);
  1075.                 /* We've lost the connection.... */
  1076.                 NoteDone = NoteError = TRUE;
  1077.             } else
  1078.                 f->m->subject = strdup (packet_data);
  1079.         }
  1080.         /* endif */ 
  1081.         else if (packet_type == STX) {
  1082.             /* Validate the packet       */
  1083.             /* and write it to the file. */
  1084.             recvcnt = recvbuf (usock, &packet_data[0], packet_size + 1);
  1085.             if (recvcnt == -1) {
  1086.                 if (FBBtrace) {
  1087.                     tcmdprintf (lostremote);
  1088.                     tcmdprintf ("\n");
  1089.                 }
  1090.                 log (f->m->user, lostremote);
  1091.                 /* We've lost the connection.... */
  1092.                 NoteDone = NoteError = TRUE;
  1093.             } else {
  1094.                 /* Write to disk */
  1095.                 if (iFile)
  1096.                     fwrite (packet_data, (unsigned int) recvcnt, 1, iFile);
  1097.  
  1098.                 /* add the data to the rx_checksum count. */
  1099.                 for (rx_checksumctr = 0; rx_checksumctr < packet_size; rx_checksumctr++)
  1100.                     rx_checksum += (unsigned char) packet_data[rx_checksumctr];
  1101.             }
  1102.         }
  1103.         /* endif */ 
  1104.         else if (packet_type == EOT) {
  1105.             /* Close the file.                  */
  1106.             /* Validate the Checksum.           */
  1107.             /* erase the file if Checksum fails.*/
  1108.             /* Get ready to read next message.  */
  1109.  
  1110.             if (packet_size == 256)
  1111.                 packet_size = 0;
  1112.             if (packet_size != (unsigned int) ((-(int) rx_checksum) & 0xff)) {
  1113.                 NoteDone = NoteError = TRUE;
  1114.                 usputs (usock, "*** CHECKSUM ERROR\n");
  1115.                 if (FBBtrace)
  1116.                     tcmdprintf ("FBBCMP: Checksum Error in message data\n");
  1117.                 log (f->m->user, "Checksum Error in message data");
  1118.             } else if (FBBtrace)
  1119.                 tcmdprintf ("FBBCMP: YAPP Message Checksum verified\n");
  1120.             /* Close the data file. */
  1121.             if (iFile)
  1122.                 (void) fclose (iFile);
  1123.             iFile = NULLFILE;
  1124.  
  1125.             /* We're done with this message. Return. */
  1126.             NoteDone = TRUE;
  1127.         }        /* endif */
  1128.     }            /* End while !NoteDone */
  1129.  
  1130.     if (!NoteError) {
  1131.         kwait (NULL);
  1132.         AllocDataBuffers (f);
  1133.         rc = Decode (usock, f->iFile, f->oFile, f->lzhuf, 1, FBBtrace);
  1134.         FreeDataBuffers (f);
  1135.         kwait (NULL);
  1136.         if (!rc) {
  1137.             if (FBBtrace)
  1138.                 tcmdprintf (ErrorDecode, rc);
  1139.             log (f->m->user, ErrorDecode, rc);
  1140.             NoteError = TRUE;
  1141.         }
  1142.     }
  1143.     if (iFile != NULLFILE)
  1144.         (void) fclose (iFile);
  1145.  
  1146.     /* delete compressed file. */
  1147.     unlink (f->iFile);
  1148.  
  1149.     /* Set the socket back to it's orginal mode. */
  1150.     (void) sockmode (usock, oldmode);
  1151.     if (!NoteError)
  1152.         return 1;
  1153.     else
  1154.         return 0;
  1155. }
  1156.  
  1157.  
  1158.  
  1159. /* Receive a buffer from a socket, returning # chars read.
  1160.  */
  1161. static int 
  1162. recvbuf (int s, char *buf, unsigned len)
  1163. {
  1164. int c;
  1165. int cnt = 0;
  1166.  
  1167.     while (len-- > 1) {
  1168.         if ((c = recvchar (s)) == EOF) {
  1169.             cnt = -1;
  1170.             break;
  1171.         }
  1172.         if (buf != NULLCHAR)
  1173.             *buf++ = (char) c;
  1174.         cnt++;
  1175.     }
  1176.     return cnt;
  1177. }
  1178. #endif
  1179.  
  1180.  
  1181.  
  1182. #ifdef XFWD
  1183. int 
  1184. send_lzhuf (struct fwd *f, char *txtFileName)
  1185. {
  1186. int oldmode;        /* Socket Mode holder. */
  1187. int rc, c;
  1188. int Error;
  1189. int usock;
  1190. FILE *binFile;
  1191. char binFileName[80];
  1192. int16 newchecksum = 0;
  1193.  
  1194.     /* User socket */
  1195.     usock = f->m->user;
  1196.  
  1197.     /* Encode code. */
  1198.     (void) tmpnam (binFileName);
  1199.  
  1200.     Error = FALSE;
  1201.  
  1202.     kwait (NULL);
  1203.     AllocDataBuffers (f);
  1204.     rc = Encode (usock, txtFileName, binFileName, f->lzhuf, Xtrace);
  1205.     FreeDataBuffers (f);
  1206.     kwait (NULL);
  1207.     if (!rc) {
  1208.         if (Xtrace)
  1209.             tcmdprintf (ErrorEncode, rc);
  1210.         log (f->m->user, ErrorEncode, rc);
  1211.         Error = TRUE;
  1212.         unlink (binFileName);    /* just in case */
  1213.     }
  1214.     unlink (txtFileName);
  1215.  
  1216.     if (Error) {
  1217.         tprintf ("SS 0\n");
  1218.         return 0;
  1219.     }
  1220.     /* open the compressed data file. */
  1221.     /* Now... we're going to read from the file and close it when we exit. */
  1222.  
  1223.     kwait (NULL);
  1224.  
  1225.     /* Open the input file. */
  1226.     binFile = fopen (binFileName, "rb");
  1227.     if (binFile == NULLFILE)
  1228.         return 0;
  1229.  
  1230.     kwait (NULL);
  1231.  
  1232.     /* Calculate checksum */
  1233.     while ((c = fgetc (binFile)) != EOF)
  1234.         newchecksum += (int16) c;
  1235.  
  1236.     rewind (binFile);
  1237.     kwait (NULL);
  1238.  
  1239.     tprintf ("SS %ld %u\n", filelength (fileno (binFile)), newchecksum);
  1240.     if (Xtrace)
  1241.         tcmdprintf ("XFWD: Sending 'SS %ld %u'\n", filelength (fileno (binFile)), newchecksum);
  1242.  
  1243.     /* Set the socket to Binary mode since we'll be sending Binary data. */
  1244.     oldmode = sockmode (usock, SOCK_BINARY);
  1245.  
  1246.     while ((c = fgetc (binFile)) != EOF)
  1247.         tputc (uchar (c));
  1248.  
  1249.     /* Terminate. */
  1250.     (void) fclose (binFile);
  1251.  
  1252.     /* Delete binFileName */
  1253.     unlink (binFileName);
  1254.  
  1255.     /* Set the socket back to it's orginal mode. */
  1256.     (void) sockmode (usock, oldmode);
  1257.     return 1;
  1258. }
  1259.  
  1260.  
  1261.  
  1262. int 
  1263. recv_lzhuf (struct fwd *f, int msgsize, int16 * newchecksum)
  1264. {
  1265. int c;
  1266. int Error = FALSE;
  1267. int rc;
  1268. int oldmode;        /* Socket Mode holder. */
  1269. FILE *iFile = NULLFILE;
  1270. int usock;
  1271.  
  1272.     *newchecksum = 0;
  1273.  
  1274.     /* User socket */
  1275.     usock = f->m->user;
  1276.  
  1277.     /* Set the socket to Binary mode since we'll be sending Binary data. */
  1278.     oldmode = sockmode (usock, SOCK_BINARY);
  1279.  
  1280.     iFile = fopen (f->iFile, "wb");
  1281.     if (iFile == NULLFILE)
  1282.         return 0;
  1283.  
  1284.     while (msgsize--) {
  1285.         /* Get the data. */
  1286.         c = recvchar (usock);
  1287.         *newchecksum += (int16) c;
  1288.         fputc (c, iFile);
  1289.     }
  1290.  
  1291.     (void) fclose (iFile);
  1292.     AllocDataBuffers (f);
  1293.     rc = Decode (usock, f->iFile, f->oFile, f->lzhuf, 0, Xtrace);
  1294.     FreeDataBuffers (f);
  1295.     if (!rc) {
  1296.         if (Xtrace)
  1297.             tcmdprintf (ErrorDecode, rc);
  1298.         log (f->m->user, ErrorDecode, rc);
  1299.         Error = TRUE;
  1300.     }
  1301.     /* delete compressed file. */
  1302.     unlink (f->iFile);
  1303.  
  1304.     kwait (NULL);
  1305.  
  1306.     /* Set the socket back to it's orginal mode. */
  1307.     (void) sockmode (usock, oldmode);
  1308.     if (!Error)
  1309.         return 1;
  1310.     else
  1311.         return 0;
  1312. }
  1313. #endif
  1314.  
  1315.  
  1316.  
  1317. #ifdef STANDALONE
  1318. int 
  1319. kwait (volatile void *event)
  1320. {
  1321. }
  1322.  
  1323.  
  1324.  
  1325. void
  1326. main (argc, argv, envp)
  1327. int argc;
  1328. char *argv[];
  1329. char *envp[];
  1330. {
  1331.     struct fwd f;
  1332.  
  1333.     AllocDataBuffers (&f);
  1334.     if (argv[1][0] == 'd')
  1335.         Decode (0, argv[2], argv[3], f.lzhuf, 0, FBBtrace);
  1336.     else
  1337.         Encode (0, argv[2], argv[3], f.lzhuf, FBBtrace);
  1338. }
  1339. #endif
  1340. #endif
  1341.